///import AI.AIGoBang;
import java.util.Enumeration;
import java.util.Vector;

import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Canvas;

/**
 * GameEngine class provides a basic game engine.
 */
public class GameEngine extends Canvas implements Runnable {

	///static public GameCanvasProxy canvas;
	///GameEngine canvas;
	private Graphics graphics;
	
	public GameManage gameManage;
	private GameModel models;
	AIGoBang m_aiGoBang;
	private Vector 	  views;
	private int		  fps;
	
	private boolean paused;
	public static boolean stoped;
	static public int s_gameFrame;
	
	public static Graphics s_g;
	
	private GameView	   m_view;
	
	public static int s_ScreenWidth;
	public static int s_ScreenHeight;
	/**
	 * Creates a Game Engine with the specified
	 * Game model attached. The game runs at the
	 * specified fps.
	 * 
	 * @param model game model.
	 * @param fps frames per second.
	 */
	protected GameEngine(/*GameModel model,*/ int fps) {
		///this.canvas = new GameCanvasProxy();
		///canvas = this;
		this.gameManage = new GameManage(this);
		
		this.views  = new Vector();
		///this.canvas.repaint();
		///this.graphics = this.canvas.getGraphics();
		///this.models   = model;
		//move to paint
	///	this.m_aiGoBang = new AIGoBang();
		this.stoped	  = true;
		this.fps	  = fps;
		setFullScreenMode(true);
		s_ScreenWidth =   getWidth();
			s_ScreenHeight =  getHeight();	
		this.gameManage.setGameState(DEF.GS_INIT);
	}

	/**
	 * Gets the drawing area.
	 * 
	 * @return drawing area.
	 */
	public Displayable getDrawingArea() {
		return this;
	}
	
	/**
	 * Starts the Game.
	 */
	public void start() {
		if (stoped) {			
			Thread t = new Thread(this);
			t.start();
		}
	}
	
	/**
	 * Stops the Game.
	 */
	 public void stop() {
		if (!stoped) {			
			this.stoped = true;
		}
	}

	/**
	 * Resumes the Game.
	 */
	public void resume() {
		synchronized (this) {
			if (paused) {
				this.paused = false;
			}
			this.notifyAll();
		}
	}
	
	/**
	 * Pauses the Game.
	 */
	public void pause() {
		synchronized (this) {			
			if (!paused) {
				this.paused = true;
			}
		}
	}
	
	/**
	 * Attaches the specified view to the
	 * engine.
	 * 
	 * @param view some view.
	 */
	public void attach(GameView view) {
		//if (!this.views.contains(view)) {
		//	this.views.addElement(view);
			this.setView(view);
	///	}
	}
	
	/**
	 * Detaches the specified view from the
	 * engine.
	 * 
	 * @param view some view.
	 */
	public void detach(GameView view) {
		////this.views.removeElement(view);
	}
	
	/* (non-Javadoc)
	 * @see javax.microedition.lcdui.game.GameCanvas#paint(javax.microedition.lcdui.Graphics)
	 */
	public void setView(GameView view)
	{
		m_view = view;
	}
	public void paint(Graphics g) {
		s_g = g;
		
		//update the draw graphics
//		Enumeration enumeration = this.views.elements();
//		while (enumeration.hasMoreElements()) {
//			GameView view = (GameView) enumeration.nextElement();
//			view.render(g,gameManage.getGameState());
//		}
		m_view.render(g,gameManage.getGameState());
		
	}

	/**
	 * Game Loop
	 */
	public void run() {
		GameEngine.stoped = false;
		if(m_aiGoBang==null)
		  m_aiGoBang = new AIGoBang();
		while (!stoped) {
			
			try {
//				synchronized (this) {
//					if (paused) {
//						this.wait();
//					}
//				}
				if (paused)
					 continue;
				long interval = System.currentTimeMillis();
				//
				s_gameFrame ++;
				GameInputKey.keyUpdate();
				//int keys = 1;
				//this.models.AI(keys, this.canvas.getWidth(), this.canvas.getHeight());
				//update the logic 
				gameManage.gameUpdate();
				
				repaint();
				/////this.paint(this.canvas.getGraphics());
				serviceRepaints();///at once repaint!!
				interval = System.currentTimeMillis() - interval;
				interval = interval > 0 ? ((1000 / fps) - interval) : 0x00;
				Thread.sleep(interval > 0 ? interval: 0x00 );
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		GameEngine.stoped = true;
		
		GoBang.s_display.setCurrent(null);
	    GoBang.s_midlet.quitApp();
	}
	
	
	// add  new codes int the below.
	//here...
	public static int getScreenWidth()
	{
		return s_ScreenWidth;
	}
	
	public static int getScreenHeight()
	{
		return s_ScreenHeight;
	}
	
	public static Graphics getGraphics() {
		return s_g;
	}
	

	protected void keyPressed(int keycode)
	{
		GameInputKey.keyPressed(keycode);
	}
	
	protected void keyReleased(int keycode)
	{
		GameInputKey.keyReleased(keycode);
	}
	
	protected void showNotify()
	{
		GameView.s_bRefreshAll = true;
	}
	
	protected void hideNotify()
	{
		
	}
	
	/*
	public class GameCanvasProxy extends Canvas {
		public  Graphics s_g;
		protected GameCanvasProxy() {
			setFullScreenMode(true);
		}

		public Graphics getGraphics() {
			return s_g;
		}
		
		public void paint(Graphics g) {
			s_g = g;
		}

		protected void keyPressed(int keycode)
		{
			GameInputKey.keyPressed(keycode);
		}
		
		protected void keyReleased(int keycode)
		{
			GameInputKey.keyReleased(keycode);
		}
		
		protected void showNotify()
		{
			
		}
		
		protected void hideNotify()
		{
			
		}
	}
	*/
}
